package org.annoflow.javassist.test;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;

import org.annoflow.javassist.AnnoTranslator;
import org.annoflow.javassist.ConfigParser;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.Loader;
import javassist.NotFoundException;

import junit.framework.TestCase;


public class JavassistTestCase extends TestCase
{
	ClassPool pool;
	ClassLoader loader;
	AnnoTranslator translator;
	public void setUp()
	{
		try
		{
			pool = new ClassPool();
			pool.appendClassPath("bin");
			pool.appendSystemPath();
			translator= new AnnoTranslator(new ConfigParser(new File("default.conf"),pool));
			loader = this.getClass().getClassLoader();
//			loader = new Loader(pool);
//			try 
//			{
//				((Loader)loader).addTranslator(pool, translator);
//			}
//			catch (CannotCompileException e)
//			{
//				e.printStackTrace();
//			}
		}
		catch (NotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	public Object runMethod(String classToLoad, String methodToTest, Class<?>[] methodToTestArgs,
			Object argsToTest) throws Exception
	{
		Class<?> rewrittenClass = loadClass(classToLoad);
		Method methodToRun = getClassMethod(rewrittenClass, methodToTest, methodToTestArgs);
		Object objectReturned = invokeMethod(methodToRun, argsToTest);
		return objectReturned;
	}

	private Object invokeMethod(Method methodToRun, Object args)
			throws Exception
	{
		Object createdObject = null;
		createdObject = (Object) methodToRun.invoke(null, (Object[]) args);
		return createdObject;
	}

	private Method getClassMethod(Class<?> rewrittenClass, String methodName, Class<?>[] args) throws Exception
	{
		Method methodToRun = null;
		// Strange.....
		if (args == null)
		{
			methodToRun = rewrittenClass.getDeclaredMethod(methodName, (Class[]) null);
		}
		else
		{
			methodToRun = rewrittenClass.getDeclaredMethod(methodName, args);
		}
		return methodToRun;
	}

	protected Class<?> loadClass(String classToLoad) throws Exception
	{
		return loader.loadClass(classToLoad);
	}
}
